# This script downloads the boost process (header-only) library, which is not (yet)
# accepted to boost. This script downloads and installs the 2010 version; see
#   http://www.highscore.de/boost/gsoc2010/
# and patches it to be compatible with recent boost versions and spawning Windows GUI applications.
URL = "http://www.highscore.de/boost/gsoc2010/process.zip"
VERSIONS = ["2010"] 
DEFAULT_VERSION = "2010"

from source.builders import DownloadAndCopyBuilder
import os, ext.patch, shutil

class BoostProcessBuilder( DownloadAndCopyBuilder ):
  def targetpath(self):
    return os.path.join( self.runtime.config.directories.enviro, "boost_process_%(VERSION)s" % {"VERSION" : self.version} )

  def patch(self):
    os.chdir( self.extractedpath )
 
  # Patch stream_behavior.hpp to correctly create and inherit NULL-iostream handles for windows GUI applications
    patchstr = """
--- boost/process/stream_behavior.hpp
+++ boost/process/stream_behavior.hpp
@@ -67,7 +67,7 @@
     : h_(h, handle::dont_close)
     {
 #if defined(BOOST_WINDOWS_API)
-        if (h != INVALID_HANDLE_VALUE)
+        if ((h != INVALID_HANDLE_VALUE) && (h != NULL))
         {
             if (!SetHandleInformation(h_.native(), HANDLE_FLAG_INHERIT,
                 HANDLE_FLAG_INHERIT))
@@ -300,15 +300,7 @@
         if (!child_end.valid())
             BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("open(2) failed");
 #elif defined(BOOST_WINDOWS_API)
-        DWORD access = (stype == input_stream) ? GENERIC_READ : GENERIC_WRITE;
-        handle child_end = CreateFileA("NUL", access, 0, NULL, OPEN_EXISTING,
-            FILE_ATTRIBUTE_NORMAL, NULL);
-        if (!child_end.valid())
-            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateFile() failed");
-        if (!SetHandleInformation(child_end.native(), HANDLE_FLAG_INHERIT,
-            HANDLE_FLAG_INHERIT))
-            BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR(
-                "SetHandleInformation() failed");
+      handle child_end(NULL, handle::dont_close);
 #endif
         return stream_ends(child_end, handle());
     }
"""
    p = ext.patch.fromstring(patchstr)
    print "Patch applied to boost/process/stream_behavior.hpp: ", p.apply()
    
  # Patch operations.hpp to include exception definitions in recent boost versions
    patchstr = """
--- boost/process/operations.hpp
+++ boost/process/operations.hpp
@@ -48,6 +48,7 @@
 #include <boost/process/stream_ends.hpp>
 #include <boost/process/handle.hpp>
 #include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/system/system_error.hpp>
 #include <boost/throw_exception.hpp>
"""
    p = ext.patch.fromstring(patchstr)
    print "Patch applied to boost/process/operations.hpp: ", p.apply()

  def install( self ):
    if os.path.exists( self.targetpath() ):
      shutil.rmtree( self.targetpath() )

    sourcedir = self.extractedpath + os.sep + "boost"
    self.copydir( sourcedir, self.targetpath() + os.sep + "include" + os.sep + "boost")

BUILDER = BoostProcessBuilder
